package com.smart.community.user.controller;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.feign.user.dto.UserDTO;
import com.smart.community.feign.user.dto.NormalUserCreateDTO;
import com.smart.community.user.dto.RoleDTO;
import com.smart.community.user.entity.User;
import com.smart.community.user.service.RoleService;
import com.smart.community.user.service.UserService;
import com.smart.community.user.vo.RoleVO;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Objects;

/**
 * 用户服务Feign接口控制器
 * 提供用户管理相关的Feign调用接口
 * 
 * @author Wu.Liang
 * @since 2025-01-08
 */
@Slf4j
@RestController
@RequestMapping("/feign/user")
@Tag(name = "用户服务Feign接口", description = "用户服务Feign调用相关接口")
public class UserFeignController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    /**
     * 根据用户ID获取用户信息
     * 
     * @param userId 用户ID
     * @return 用户信息DTO
     * @throws Exception 统一异常
     */
    @GetMapping("/user/info/{userId}")
    @Operation(summary = "根据用户ID获取用户信息", description = "根据用户ID获取用户信息")
    public UserDTO getUserById(@PathVariable Long userId) throws Exception {
        log.info("根据用户ID获取用户信息，用户ID：{}", userId);
        
        User user = userService.getById(userId);
        if (user == null) {
            return null;
        }
        
        return convertToUserDTO(user);
    }

    /**
     * 根据用户名获取用户信息
     * 
     * @param username 用户名
     * @return 用户信息DTO
     * @throws Exception 统一异常
     */
    @GetMapping("/user/info/username/{username}")
    @Operation(summary = "根据用户名获取用户信息", description = "根据用户名获取用户信息")
    public UserDTO getUserByUsername(@PathVariable String username) throws Exception {
        log.info("根据用户名获取用户信息，用户名：{}", username);
        
        // 使用LambdaQueryWrapper查询
        User user = userService.lambdaQuery().eq(User::getUsername, username).one();
        if (user == null) {
            return null;
        }
        
        return convertToUserDTO(user);
    }

    /**
     * 根据身份证号查询用户
     * 
     * @param idCard 身份证号
     * @return 用户信息DTO
     * @throws Exception 统一异常
     */
    @GetMapping("/user/info/idcard/{idCard}")
    @Operation(summary = "根据身份证号查询用户", description = "根据身份证号查询用户信息")
    public UserDTO getUserByIdCard(@PathVariable String idCard) throws Exception {
        log.info("根据身份证号查询用户，身份证号：{}", idCard);
        
        User user = userService.getUserByIdCard(idCard);
        if (user == null) {
            return null;
        }
        
        return convertToUserDTO(user);
    }

    /**
     * 根据手机号查询用户
     * 
     * @param phone 手机号
     * @return 用户信息DTO
     * @throws Exception 统一异常
     */
    @GetMapping("/user/info/phone/{phone}")
    @Operation(summary = "根据手机号查询用户", description = "根据手机号查询用户信息")
    public UserDTO getUserByPhone(@PathVariable String phone) throws Exception {
        log.info("根据手机号查询用户，手机号：{}", phone);
        
        try {
            User user = userService.getUserByPhone(phone);
            if (user == null) {
                log.info("未找到用户，手机号：{}", phone);
                return null;
            }
            
            UserDTO userDTO = convertToUserDTO(user);
            log.info("查询用户成功，用户ID：{}，手机号：{}", userDTO.getId(), phone);
            return userDTO;
        } catch (Exception e) {
            log.error("根据手机号查询用户失败，手机号：{}，错误：{}", phone, e.getMessage(), e);
            // 返回null而不是抛出异常，避免Feign调用失败
            return null;
        }
    }

    /**
     * 创建普通用户
     * 
     * @param userData 用户数据
     * @return 创建的用户ID
     * @throws Exception 统一异常
     */
    @PostMapping("/user/create/normal")
    @Operation(summary = "创建普通用户", description = "创建普通用户，用于住户管理")
    public Long createNormalUser(@RequestBody NormalUserCreateDTO dto) throws Exception {
        return userService.createNormalUser(dto);
    }

    /**
     * 创建用户
     * 
     * @param userDTO 用户信息DTO
     * @return 创建的用户信息
     * @throws Exception 统一异常
     */
    @PostMapping("/user/create")
    @Operation(summary = "创建用户", description = "创建用户")
    public UserDTO createUser(@RequestBody UserDTO userDTO) throws Exception {
        log.info("创建用户，用户信息：{}", userDTO);
        
        // 转换为User实体
        User user = new User();
        user.setUsername(userDTO.getUsername());
        user.setRealName(userDTO.getRealName());
        user.setPhone(userDTO.getPhone());
        user.setEmail(userDTO.getEmail());
        user.setIdCard(userDTO.getIdCard());
        user.setGender(userDTO.getGender());
        user.setBirthday(userDTO.getBirthday());
        user.setUserType(userDTO.getUserType());
        user.setStatus(userDTO.getStatus());
        user.setAuditStatus(userDTO.getAuditStatus());
        user.setIsAdminProtected(userDTO.getIsAdminProtected());
        user.setPropertyCompanyId(userDTO.getPropertyCompanyId());
        user.setCommunityId(userDTO.getCommunityId());
        user.setBuildingId(userDTO.getBuildingId());
        user.setUnitId(userDTO.getUnitId());
        user.setHouseholdId(userDTO.getHouseholdId());
        
        // 设置默认密码为手机号（加密）
        if (StringUtils.hasText(userDTO.getPhone())) {
            user.setPassword(SecurityUtils.encryptPassword(userDTO.getPhone()));
        } else {
            user.setPassword(SecurityUtils.encryptPassword("123456"));
        }
        
        // 创建用户
        boolean success = userService.save(user);
        if (success) {
            return convertToUserDTO(user);
        } else {
            return null;
        }
    }

    /**
     * 更新用户信息
     * 
     * @param userDTO 用户信息DTO
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @PostMapping("/user/update")
    @Operation(summary = "更新用户信息", description = "更新用户信息")
    public Boolean updateUser(@RequestBody UserDTO userDTO) throws Exception {
        log.info("更新用户信息，用户ID：{}", userDTO.getId());
        
        // 根据ID查询现有用户
        User existingUser = userService.getById(userDTO.getId());
        if (existingUser == null) {
            log.error("用户不存在，用户ID：{}", userDTO.getId());
            return false;
        }
        
        // 更新用户信息
        existingUser.setUsername(userDTO.getUsername());
        existingUser.setRealName(userDTO.getRealName());
        existingUser.setPhone(userDTO.getPhone());
        existingUser.setEmail(userDTO.getEmail());
        existingUser.setIdCard(userDTO.getIdCard());
        existingUser.setGender(userDTO.getGender());
        existingUser.setBirthday(userDTO.getBirthday());
        existingUser.setUserType(userDTO.getUserType());
        existingUser.setStatus(userDTO.getStatus());
        existingUser.setAuditStatus(userDTO.getAuditStatus());
        existingUser.setIsAdminProtected(userDTO.getIsAdminProtected());
        existingUser.setPropertyCompanyId(userDTO.getPropertyCompanyId());
        existingUser.setCommunityId(userDTO.getCommunityId());
        existingUser.setBuildingId(userDTO.getBuildingId());
        existingUser.setUnitId(userDTO.getUnitId());
        existingUser.setHouseholdId(userDTO.getHouseholdId());
        
        // 更新用户
        boolean success = userService.updateById(existingUser);
        if (success) {
            log.info("用户信息更新成功，用户ID：{}", userDTO.getId());
        } else {
            log.error("用户信息更新失败，用户ID：{}", userDTO.getId());
        }
        
        return success;
    }

    /**
     * 验证用户密码
     * 
     * @param userDTO 用户信息（包含密码）
     * @return 验证结果
     * @throws Exception 统一异常
     */
    @PostMapping("/user/validate")
    @Operation(summary = "验证用户密码", description = "验证用户密码")
    public Boolean validatePassword(@RequestBody UserDTO userDTO) throws Exception {
        log.info("验证用户密码，用户名：{}", userDTO.getUsername());
        
        // 根据用户名查询用户
        User user = userService.lambdaQuery().eq(User::getUsername, userDTO.getUsername()).one();
        if (user == null) {
            return false;
        }
        
        // 验证密码
        String encryptedPassword = SecurityUtils.encryptPassword(userDTO.getPassword());
        return encryptedPassword.equals(user.getPassword());
    }

    /**
     * 删除用户
     * 
     * @param userId 用户ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/user/delete/{userId}")
    @Operation(summary = "删除用户", description = "删除用户")
    public Boolean deleteUser(@PathVariable Long userId) throws Exception {
        log.info("删除用户，用户ID：{}", userId);
        
        return userService.removeById(userId);
    }

    /**
     * 批量获取用户信息
     * 
     * @param userIds 用户ID列表
     * @return 用户信息列表
     * @throws Exception 统一异常
     */
    @PostMapping("/user/batch")
    @Operation(summary = "批量获取用户信息", description = "批量获取用户信息")
    public List<UserDTO> getUsersByIds(@RequestBody List<Long> userIds) throws Exception {
        log.info("批量获取用户信息，用户ID列表：{}", userIds);
        
        List<User> users = userService.listByIds(userIds);
        return users.stream().map(this::convertToUserDTO).collect(Collectors.toList());
    }

    /**
     * 根据角色获取用户列表
     * 
     * @param roleCode 角色编码
     * @return 用户列表
     * @throws Exception 统一异常
     */
    @GetMapping("/user/list/role/{roleCode}")
    @Operation(summary = "根据角色获取用户列表", description = "根据角色获取用户列表")
    public List<UserDTO> getUsersByRole(@PathVariable String roleCode) throws Exception {
        log.info("根据角色获取用户列表，角色编码：{}", roleCode);
        
        // 通过角色服务获取用户列表
        List<User> users = userService.getUsersByRoleCode(roleCode);
        return users.stream().map(this::convertToUserDTO).collect(Collectors.toList());
    }

    /**
     * 根据社区ID获取用户列表
     * 
     * @param communityId 社区ID
     * @return 用户列表
     * @throws Exception 统一异常
     */
    @GetMapping("/user/list/community/{communityId}")
    @Operation(summary = "根据社区ID获取用户列表", description = "根据社区ID获取用户列表")
    public List<UserDTO> getUsersByCommunity(@PathVariable Long communityId) throws Exception {
        log.info("根据社区ID获取用户列表，社区ID：{}", communityId);
        
        List<User> users = userService.lambdaQuery().eq(User::getCommunityId, communityId).list();
        return users.stream().map(this::convertToUserDTO).collect(Collectors.toList());
    }

    /**
     * 根据物业公司ID获取用户列表
     * 
     * @param propertyCompanyId 物业公司ID
     * @return 用户列表
     * @throws Exception 统一异常
     */
    @GetMapping("/user/list/property/{propertyCompanyId}")
    @Operation(summary = "根据物业公司ID获取用户列表", description = "根据物业公司ID获取用户列表")
    public List<UserDTO> getUsersByPropertyCompany(@PathVariable Long propertyCompanyId) throws Exception {
        log.info("根据物业公司ID获取用户列表，物业公司ID：{}", propertyCompanyId);
        
        List<User> users = userService.lambdaQuery().eq(User::getPropertyCompanyId, propertyCompanyId).list();
        return users.stream().map(this::convertToUserDTO).collect(Collectors.toList());
    }

    /**
     * 检查用户名是否存在
     * 
     * @param username 用户名
     * @return 是否存在
     * @throws Exception 统一异常
     */
    @GetMapping("/user/check-username/{username}")
    @Operation(summary = "检查用户名是否存在", description = "检查用户名是否存在")
    public Boolean checkUsernameExists(@PathVariable String username) throws Exception {
        log.info("检查用户名是否存在，用户名：{}", username);
        
        return userService.checkUsernameExists(username);
    }

    /**
     * 检查手机号是否存在
     * 
     * @param phone 手机号
     * @return 是否存在
     * @throws Exception 统一异常
     */
    @GetMapping("/user/check-phone/{phone}")
    @Operation(summary = "检查手机号是否存在", description = "检查手机号是否存在")
    public Boolean checkPhoneExists(@PathVariable String phone) throws Exception {
        log.info("检查手机号是否存在，手机号：{}", phone);
        
        return userService.checkPhoneExists(phone);
    }

    /**
     * 检查邮箱是否存在
     * 
     * @param email 邮箱
     * @return 是否存在
     * @throws Exception 统一异常
     */
    @GetMapping("/user/check-email/{email}")
    @Operation(summary = "检查邮箱是否存在", description = "检查邮箱是否存在")
    public Boolean checkEmailExists(@PathVariable String email) throws Exception {
        log.info("检查邮箱是否存在，邮箱：{}", email);
        
        return userService.checkEmailExists(email);
    }

    /**
     * 分配用户角色
     * 
     * @param userId 用户ID
     * @param roleIds 角色ID列表
     * @throws Exception 统一异常
     */
    @PostMapping("/user/role/assign/{userId}")
    @Operation(summary = "分配用户角色", description = "为用户分配角色")
    public Void assignUserRoles(@PathVariable Long userId, @RequestBody List<Long> roleIds) throws Exception {
        log.info("分配用户角色，用户ID：{}，角色ID列表：{}", userId, roleIds);
        
        userService.assignRoles(userId, roleIds);
        return null;
    }

    /**
     * 更新用户类型
     * 
     * @param userId 用户ID
     * @param userType 用户类型
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @PutMapping("/user/type/{userId}")
    @Operation(summary = "更新用户类型", description = "更新用户类型")
    public Boolean updateUserType(@PathVariable Long userId, @RequestParam String userType) throws Exception {
        log.info("更新用户类型，用户ID：{}，用户类型：{}", userId, userType);
        
        try {
            User user = userService.getById(userId);
            if (user == null) {
                log.warn("用户不存在，用户ID：{}", userId);
                return false;
            }
            
            user.setUserType(userType);
            user.setUpdateBy(SecurityUtils.getCurrentUserId());
            boolean updated = userService.updateById(user);
            
            if (updated) {
                log.info("更新用户类型成功，用户ID：{}，用户类型：{}", userId, userType);
            } else {
                log.warn("更新用户类型失败，用户ID：{}，用户类型：{}", userId, userType);
            }
            
            return updated;
        } catch (Exception e) {
            log.error("更新用户类型异常，用户ID：{}，用户类型：{}", userId, userType, e);
            return false;
        }
    }

    /**
     * 根据用户ID获取用户关联的角色信息列表
     * 
     * @param userId 用户ID
     * @return 角色信息列表
     * @throws Exception 统一异常
     */
    @GetMapping("/user/roles/{userId}")
    @Operation(summary = "根据用户ID获取用户关联的角色信息列表", description = "根据用户ID获取用户关联的角色信息列表")
    public List<RoleDTO> getUserRoles(@PathVariable Long userId) throws Exception {
        log.info("根据用户ID获取用户关联的角色信息列表，用户ID：{}", userId);
        
        try {
            // 1. 获取用户角色ID列表
            List<Map<String, Object>> userRoles = userService.getUserRoles(userId);
            if (userRoles == null || userRoles.isEmpty()) {
                log.info("用户没有分配角色，用户ID：{}", userId);
                return new ArrayList<>();
            }
            
            // 2. 提取角色ID列表
            List<Long> roleIds = userRoles.stream()
                .map(roleMap -> {
                    Object roleIdObj = roleMap.get("roleId");
                    if (roleIdObj == null) {
                        return null;
                    }
                    // 处理可能的类型转换问题
                    if (roleIdObj instanceof Integer) {
                        return ((Integer) roleIdObj).longValue();
                    } else if (roleIdObj instanceof Long) {
                        return (Long) roleIdObj;
                    } else {
                        log.warn("未知的roleId类型：{}，值：{}", roleIdObj.getClass().getName(), roleIdObj);
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
            
            if (roleIds.isEmpty()) {
                log.info("用户角色ID列表为空，用户ID：{}", userId);
                return new ArrayList<>();
            }
            
            // 3. 根据角色ID获取角色详细信息
            List<RoleDTO> roleDTOs = new ArrayList<>();
            for (Long roleId : roleIds) {
                try {
                    RoleVO roleVO = roleService.getRole(roleId);
                    if (roleVO != null && roleVO.getStatus() != null && roleVO.getStatus() == 1) {
                        // 只返回启用的角色
                        RoleDTO roleDTO = convertToRoleDTO(roleVO);
                        roleDTOs.add(roleDTO);
                    }
                } catch (Exception e) {
                    log.warn("获取角色信息失败，角色ID：{}，用户ID：{}", roleId, userId, e);
                }
            }
            
            log.info("获取用户角色信息成功，用户ID：{}，角色数量：{}", userId, roleDTOs.size());
            return roleDTOs;
            
        } catch (Exception e) {
            log.error("根据用户ID获取用户关联的角色信息列表失败，用户ID：{}", userId, e);
            return new ArrayList<>();
        }
    }

    /**
     * 将User实体转换为UserDTO
     * 
     * @param user User实体
     * @return UserDTO
     */
    private UserDTO convertToUserDTO(User user) {
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setUsername(user.getUsername());
        userDTO.setRealName(user.getRealName());
        userDTO.setPhone(user.getPhone());
        userDTO.setEmail(user.getEmail());
        userDTO.setIdCard(user.getIdCard());
        userDTO.setGender(user.getGender());
        userDTO.setBirthday(user.getBirthday());
        userDTO.setUserType(user.getUserType());
        userDTO.setStatus(user.getStatus());
        userDTO.setAuditStatus(user.getAuditStatus());
        userDTO.setIsAdminProtected(user.getIsAdminProtected());
        userDTO.setPropertyCompanyId(user.getPropertyCompanyId());
        userDTO.setCommunityId(user.getCommunityId());
        userDTO.setBuildingId(user.getBuildingId());
        userDTO.setUnitId(user.getUnitId());
        userDTO.setHouseholdId(user.getHouseholdId());
        userDTO.setCreateTime(user.getCreateTime());
        userDTO.setUpdateTime(user.getUpdateTime());
        
        return userDTO;
    }

    /**
     * 将RoleVO转换为RoleDTO
     * 
     * @param roleVO RoleVO对象
     * @return RoleDTO对象
     */
    private RoleDTO convertToRoleDTO(RoleVO roleVO) {
        if (roleVO == null) {
            return null;
        }
        
        RoleDTO roleDTO = new RoleDTO();
        roleDTO.setId(roleVO.getId());
        roleDTO.setRoleName(roleVO.getRoleName());
        roleDTO.setRoleCode(roleVO.getRoleCode());
        roleDTO.setRoleType(roleVO.getRoleType());
        roleDTO.setDataScope(roleVO.getDataScope());
        roleDTO.setDescription(roleVO.getDescription());
        roleDTO.setStatus(roleVO.getStatus());
        // 与当前RoleDTO字段保持一致
        roleDTO.setSort(roleVO.getSort());
        
        return roleDTO;
    }
}
